package com.electronic.utils;

import cn.hutool.core.collection.CollUtil;
import com.electronic.exception.ResultCode;
import com.electronic.exception.ServiceException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.util.ArrayList;

/**
 * @Author: IFCA
 * @Description: 自定义文件工具类
 */
public class IFileUtil {

    /**
     * 功能描述: 验证PDF文件是否可用
     */
    public static void verifyPdfUsable(String pdfPath) {
        PdfReader reader = null;
        try {
            // 尝试加载文档，如果没有抛出异常，则认为文件是可读的
            reader = new PdfReader(pdfPath);
        } catch (IOException e) {
            // 捕获加载文档时的异常，认为文件不可读
            throw new ServiceException(ResultCode.ERROR_FILE, "文件不可读");
        }

        //文件是否已加密
        boolean encrypted = reader.isEncrypted();
        if (encrypted) {
            throw new ServiceException(ResultCode.ERROR_FILE, "文件已加密");
        }
        //关闭阅读器
        reader.close();
    }
    /**
     * 判断是否含有电子签名
     */
    public static boolean isHasSignature(String pdfPath) {
        PdfReader reader = null;
        try {
            reader = new PdfReader(pdfPath);
            AcroFields fields = reader.getAcroFields();
            ArrayList<String> signatureNames = fields.getSignatureNames();
            if (CollUtil.isNotEmpty(signatureNames)) {
                return true;
            }
        } catch (IOException e) {
            throw new ServiceException(ResultCode.ERROR_FILE, "文件不可读");
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        return false;
    }

    /**
     * 设置响应头
     */
    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException {
        String percentEncodedFileName = percentEncode(realFileName);

        StringBuilder contentDispositionValue = new StringBuilder();
        contentDispositionValue.append("attachment; filename=")
                .append(percentEncodedFileName)
                .append(";")
                .append("filename*=")
                .append("utf-8''")
                .append(percentEncodedFileName);

        response.setHeader("Content-disposition", contentDispositionValue.toString());
    }

    /**
     * 文件名称编码
     */
    public static String percentEncode(String s) throws UnsupportedEncodingException {
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
        return encode.replaceAll("\\+", "%20");
    }

    /**
     * 输出文件流
     */
//    public static void writeBytes(String filePath, String fileStorage, String fileKey, OutputStream os) throws IOException {
//        InputStream fis = null;
//        try {
//            File file = new File(filePath);
//            //判断文件是否存在
//            if (file.exists()) {
//                //读取文件
//                fis = Files.newInputStream(file.toPath());
//            } else {
//                fis = FileStorageProvider.downloadAsInputStream(fileStorage, fileKey);
//            }
//            byte[] b = new byte[1024];
//            int length;
//            //把文件写入到输出流
//            while ((length = fis.read(b)) > 0) {
//                os.write(b, 0, length);
//            }
//        } catch (IOException e) {
//            throw e;
//        } finally {
//            if (os != null) {
//                try {
//                    //关闭
//                    os.close();
//                } catch (IOException e1) {
//                    e1.printStackTrace();
//                }
//            }
//            if (fis != null) {
//                try {
//                    //关闭
//                    fis.close();
//                } catch (IOException e1) {
//                    e1.printStackTrace();
//                }
//            }
//        }
//    }

    /**
     * 获取文件hash值
     */
    public static String getFileHash(File file) {
        try {
            // 创建一个MessageDigest对象，用于计算SHA-256哈希值
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            // 使用FileInputStream读取文件
            try (InputStream is = Files.newInputStream(file.toPath())) {
                byte[] buffer = new byte[1024];
                int read = 0;
                // 读取文件内容，并更新哈希值
                while ((read = is.read(buffer)) != -1) {
                    digest.update(buffer, 0, read);
                }
                // 获取最终的哈希值
                byte[] hashBytes = digest.digest();
                // 将哈希值转换为十六进制字符串
                StringBuilder sb = new StringBuilder();
                for (byte b : hashBytes) {
                    sb.append(String.format("%02x", b));
                }
                return sb.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 文件路径转为文件对象，并且校验文件路径是否存在
     */
    public static File filePathToFile(String filePath) {
        File file = new File(filePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        return file;
    }
}
